package org.example;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;
import java.util.Scanner;
import java.util.Set;

public class ATM {
    //所有用户的Map集合
    private static HashMap<String, User> allUser = new HashMap<String, User>();
    private static Properties properties = new Properties();
    //属性 -- 它包含了哪些值数据
    private User theUser; //表示登陆成功用户

    private Double cash = 100000.00;

    public static final Double MAX_CASH = 200000.00;

    //    当前时间
    TimeUtil time = new TimeUtil();

    static IOUtil ioUtil = new IOUtil();

    /**
     * 初始化用户配置文件
     */
    static {
//        try {
////            properties.load(new FileInputStream("/Users/cengyunke/Desktop/atm1/atm/src/main/resources/User.properties"));
////        } catch (IOException e) {
////            throw new RuntimeException(e);
////        }
        /**
         * 将所有从Properties文件中读取的用户全部放入allUser的Map集合中(手动)
         * 并将Map集合中的allUser全部序列化，储存为User.txt文件
         */
//        Set key = properties.keySet();
//        for (Object a : key
//        ) {
//            String[] str = properties.getProperty(a.toString()).split("-");
//            User user = new User(a.toString(), str[0], Double.parseDouble(str[1]));
//            allUser.put(a.toString(), user);
//            ioUtil.UserToIO(allUser);
//        }
        /**
         * 从User.txt文件中反序列化出allUser的Map集合
         */
        allUser = ioUtil.IOToUser();

    }

    public ATM() {

    }

    //运行
    public void run() {
        boolean successOrNot = this.login();
        if (successOrNot) {
            while (true) {
                String item = this.choiceMenu();
                switch (item) {
                    case "1":
                        this.query();
                        break;
                    case "2":
                        this.getMoney();
                        break;
                    case "3":
                        this.storeMoney();
                        break;
                    case "4":
                        this.changePwd();
                        break;
                    case "5":
                        this.transMoney();
                        break;
                    case "6":
                        this.exit();
                        break;
                    default:
                        System.err.println("没有该选项，请重新选择");
                        break;
                }
            }

        } else {
            System.err.println("您的卡被吞，请带上有效证件到柜台处理。");
        }
    }

    //行为 -- 它提供了哪些功能行为
    //登陆
    private boolean login() {
        for (int i = 0; i < 3; i++) {
            Scanner scan = new Scanner(System.in);
            System.out.println("请输入用户名：");
            String inputName = scan.next();
            System.out.println("请输入密码：");
            String inputPwd = scan.next();

            User LoginUser;
            /**
             * 判断当前登录的用户是存在于allUser中，并且密码是否为当前登录用户Key所对应的用户对象的密码
             */
            if ((LoginUser = allUser.get(inputName)) != null && LoginUser.getPassword().equals(inputPwd)) {
                /**
                 * 登录成功后将登录用户对象赋值给当前操作用户对象
                 */
                this.theUser = LoginUser;
                System.out.println(time.getNow() + "  登陆成功，欢迎你，用户" + inputName);
                return true;
            } else {
                System.err.println("用户名或密码有误,请重新输入！你还有" + (2 - i) + "次机会");
            }
        }
        return false;
    }

    //选择菜单
    private String choiceMenu() {
        Scanner scan = new Scanner(System.in);
        System.out.println("请选择你要执行的操作：");
        System.out.println("1、查询余额;2、取款;3、存款\n4、修改密码;5、转账;6、退出。");
        return scan.next();
    }

    //查询
    private void query() {
        System.out.println("你当前的余额是：" + this.theUser.getAccount() + "元。");
    }

    //取钱
    private void getMoney() {
        /*
            输入有效性验证；(暂时放弃)
            业务有效性验证；
           取款操作要求：
           1、不能是负数或0；
           2、只能是百元整数
           3、单笔操作不能超过2万
           4、不能超过用户的余额
           5、不能操作ATM机的现金
         */

        /**
         * 判断非法输入
         */
        while (true) {
            System.out.println("如需返回请输入 B ");
            Scanner scan = new Scanner(System.in);
            System.out.println("请输入你的取款金额:");
            String getOutMoney = scan.next();
            if (getOutMoney.equalsIgnoreCase("B")) {

                return;
            }
            if (getOutMoney.matches("(1[0-9]?[0-9]?|[2-9][0-9]?|20?0?)00")) {
                this.theUser.setAccount(this.theUser.getAccount() - Double.valueOf(getOutMoney));
                this.cash -= Double.valueOf(getOutMoney);
                ATMUtil.storeTheUser(theUser, properties);
                System.out.println(time.getNow() + "  取款操作成功，请查询确认。");
                System.out.println();
            } else {
                System.err.println("余额不足或非法输入，请检查后重试！");
            }

            if (Double.valueOf(getOutMoney) > this.theUser.getAccount()) {
                System.err.println("不好意思，您的余额不足");

                return;
            }
            /**
             * 判断是否超出本机现金
             */
            if (Double.valueOf(getOutMoney) > this.cash) {
                System.err.println("不好意思，本机现金不足");

                return;
            }

            return;
        }
    }


    //存钱
    private void storeMoney() {
         /*
           存款操作要求：
           1、不能是负数或0；
           2、只能是百元整数
           3、单笔操作不能超过2万
           4、存入的现金 + 已有现金 不能操作ATM机的最大现金量
         */
        while (true) {

            System.out.println("如需返回请输入 B ");
            Scanner scan = new Scanner(System.in);
            System.out.println("请输入你的存款金额:");
            String inputMoney = scan.next();

            if (inputMoney.equalsIgnoreCase("B")) {
                return;
            }
            if (inputMoney.matches("(1[0-9]?[0-9]?|[2-9][0-9]?|20?0?)00")) {
                this.theUser.setAccount(this.theUser.getAccount() + Double.valueOf(inputMoney));
                this.cash += Double.valueOf(inputMoney);
                ATMUtil.storeTheUser(theUser, properties);
                System.out.println(time.getNow() + "  存款操作成功，请查询确认。");
                System.out.println();
            } else {
                System.err.println("余额不足或非法输入，请检查后重试！");
            }

            if (Double.valueOf(inputMoney) + this.cash > ATM.MAX_CASH) {
                System.err.println("不好意思，本机容量不足");
                return;
            }
            return;
        }
    }

    //修改密码
    private void changePwd() {
          /*
            修改密码：
            1、长度为6位密码
            2、密码只能是全数字密码
            3、旧密码必须输入正确
            4、新密码必须与旧密码不同
            5、两次新密码必须相同
          */

        try {
            Scanner scan = new Scanner(System.in);
            System.out.println("请输入现有密码：");

            String oldPwd = scan.next();
            if (!oldPwd.equals(this.theUser.getPassword())) {
                System.err.println("原密码输入不正确");
                return;
            }
            System.out.println("请输入新的密码：");

            String newPwd = scan.next();

            if (!newPwd.matches("[0-9]{6}")) {
                System.err.println("密码长度只能是6位数字");
                return;
            }

            if (newPwd.equals(oldPwd)) {
                System.err.println("新密码不能与原密码保持一致");
                return;
            }

            System.out.println("请再次输入新密码：");

            String newPwd2 = scan.next();
            if (!newPwd.equals(newPwd2)) {
                System.err.println("两次新密码不同");
                return;
            }

            this.theUser.setPassword(newPwd);
            ATMUtil.ChangeUser(theUser, newPwd, properties);
            System.out.println(time.getNow() + "   修改密码成功，下次登陆生效");
        } catch (Exception exception) {
            System.err.println("非法输入,请检查后重试");
        }
    }


    //转帐
    private void transMoney() {
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入对方的账号：");
        String toUsername = scan.next();

        if (toUsername.equals(this.theUser.getUsername())) {
            System.err.println("不能给当前用户自己转账");
            return;
        }

        if (properties.getProperty(toUsername) == null) {
            System.err.println("该目标用户不存在");
            return;
        }

        System.out.println("请输入转账的金额：");

        String inputMoney = scan.next();
        /*
            转帐：
            1、对方账户要存在
            2、转账金额必须大于0
            3、单笔操作不能超过15万
            4、当前用户余额是否足够
         */

        if (Double.parseDouble(inputMoney) > this.theUser.getAccount()) {
            System.err.println("不好意思，余额不足");
            return;
        }

        if (inputMoney.matches("( 0[.][0-9]?[1-9]|" +
                "[1-9][.][0-9]?[0-9]?|" +
                "[1-9]|" +
                "1[0-9]?[0-9]?[0-9]?[0-9]?[.][0-9]?[0-9]?|" +
                "1[0-9]?[0-9]?[0-9]?[0-9]?|" +
                "[2-9][0-4]?[0-9]?[0-9]?[0-9]?[.][0-9]?[0-9]?|" +
                "[2-9][0-4]?[0-9]?[0-9]?[0-9]?|1[0-4]?[0-9]?[0-9]?[0-9]?[0-9]?|" +
                "1[0-5]?0?0?0?0?|" +
                "1[0-4][0-9][0-9][0-9][0-9][.][0-9][0-9]?|" +
                "1[0-5]0000[.]00?)")) {
            this.theUser.setAccount(this.theUser.getAccount() - Double.parseDouble(inputMoney));
            String[] tUser1;
            tUser1 = properties.getProperty(toUsername).split("-");
            User tUser = new User(toUsername, tUser1[0], Double.parseDouble(tUser1[1]));
            tUser.setAccount(tUser.getAccount() + Double.parseDouble(inputMoney));

            ATMUtil.storeTheUser(theUser, properties);//修改当前用户余额
            ATMUtil.storeTheUser(tUser, properties);//修改转账目标对象的余额

            System.out.println(time.getNow() + "  转账操作成功，对方到账日期约为" + time.maybeTime());
            System.out.println();
        } else {
            System.err.println("请输入正确的转账金额！");
        }
    }


    //退出
    private void exit() {
        System.out.println("谢谢你的使用，期待下次为你服务");
        System.exit(0);//关闭虚拟机,参数int是代表的是以什么状态下完成关闭，0代表正常关闭。
    }
}
